part of '../widgets.dart';

/// [VanRow] 点击时触发
typedef VanRowClickCallback = GestureTapCallback;

/// [VanCol] 点击时触发
typedef VanColClickCallback = GestureTapCallback;

class VanRow extends StatelessWidget {
  /// props - 列元素之间的间距（单位为 px）- 水平方向
  final double gutter;

  /// props - 列元素之间的间距（单位为 px）- 垂直方向
  final double? runGutter;

  /// props - 主轴对齐方式，可选值为 end center  space-around space-between(默认: start)
  final WrapAlignment justify;

  /// props - 交叉轴对齐方式，可选值为 center bottom(默认: top)
  final WrapAlignment align;

  /// props - 是否自动换行(默认: true)
  final bool wrap;

  /// events - 点击时触发
  final VanRowClickCallback? onClick;

  /// slots - default
  final List<Widget> children;

  /// Layout 布局 - Row
  const VanRow({
    super.key,
    this.gutter = 0,
    this.runGutter,
    this.justify = WrapAlignment.start,
    this.align = WrapAlignment.start,
    this.wrap = true,
    this.onClick,
    this.children = const [],
  }) : assert(gutter >= 0);

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (ctx, ctt) {
      if (!wrap) {
        Widget widget = SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: Row(mainAxisSize: MainAxisSize.max, children: children),
        );
        if (gutter > 0) {
          widget = UnconstrainedBox(
            clipBehavior: Clip.hardEdge,
            alignment: Alignment.center,
            child: SizedBox(width: ctt.maxWidth + gutter, child: widget),
          );
        }
        widget = VanProvider<_VanRowData>(
          provide: _VanRowData(gutter: gutter, width: ctt.maxWidth + gutter, wrap: wrap),
          child: widget,
        );
        if (onClick != null) widget = GestureDetector(onTap: onClick, child: widget);
        return widget;
      }

      Widget widget;

      if (gutter <= 0 || children.isEmpty) {
        widget = Wrap(alignment: justify, runAlignment: align, runSpacing: runGutter ?? gutter, spacing: gutter, children: children);
      } else {
        widget = Wrap(alignment: justify, runAlignment: align, runSpacing: runGutter ?? gutter, children: children);
        if (gutter > 0) {
          widget = UnconstrainedBox(
            clipBehavior: Clip.hardEdge,
            alignment: Alignment.center,
            child: SizedBox(width: ctt.maxWidth + gutter, child: widget),
          );
        }
        widget = VanProvider<_VanRowData>(
          provide: _VanRowData(gutter: gutter, width: ctt.maxWidth + gutter, wrap: wrap),
          child: widget,
        );
      }

      if (onClick != null) widget = GestureDetector(onTap: onClick, child: widget);
      return SizedBox(width: double.infinity, child: widget);
    });
  }
}

class VanCol extends StatelessWidget {
  /// props - 列元素宽度
  final int span;

  /// props - 列元素偏移距离
  final int offset;

  /// events - 点击时触发
  final VanColClickCallback? onClick;

  /// slots - default
  final Widget? child;

  static final _empty = Container();

  const VanCol({super.key, this.span = 1, this.offset = 0, this.onClick, this.child})
      : assert(span >= 1 && span <= 24),
        assert(offset >= 0 && offset <= 24);

  @override
  Widget build(BuildContext context) {
    Widget widget = child ?? _empty;
    return LayoutBuilder(builder: (ctx, ctt) {
      final _VanRowData? data = _VanRowData.of(context);
      final gutter = data?.gutter ?? 0;
      double? maxWidth = data?.width;
      maxWidth ??= ctt.maxWidth;
      maxWidth ??= MediaQuery.of(context).size.width;
      final step = (maxWidth) / 24;

      final width = span * step;

      if (gutter > 0) {
        widget = Padding(
          padding: EdgeInsets.symmetric(horizontal: gutter / 2),
          child: widget,
        );
      }

      if (offset <= 0) {
        widget = SizedBox(width: width, child: widget);
      } else {
        widget = Container(
          width: width,
          margin: EdgeInsets.only(left: offset * step),
          child: widget,
        );
      }

      if (onClick != null) widget = GestureDetector(onTap: onClick, child: widget);

      return VanProvider<_VanRowData>(child: widget);
    });
  }
}

@immutable
class _VanRowData with VanProvide {
  final double gutter;
  final double width;
  final bool wrap;

  static of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<VanProvider<_VanRowData>>()?.provide;
  }

  const _VanRowData({required this.gutter, required this.width, required this.wrap});
}
